import requests
from typing import Dict, List, Any, Optional, Tuple
from tools.log_util import INFO, ERROR, WARNING


# ================== 配置管理 ==================

class Config:
    """统一配置管理类"""
    
    # API配置
    API_BASE_URL = 'https://cgboss.yuntiancloud.com/api'
    DEFAULT_PAGE_SIZE = 100
    REQUEST_TIMEOUT = 30
    
    # 显示配置
    DEFAULT_VMID_PER_LINE = 15
    MAX_OSSTATE_WIDTH = 30
    MAX_STATUS_WIDTH = 15
    
    # 认证Token（后续可以改为从配置文件或环境变量获取）
    AUTH_TOKEN = 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEzMjk4LCJpc3MiOiJjZ2Jvc3MiLCJleHAiOjE3NTYyNjIxMTIsIm5iZiI6MTc1MzY3MDExMiwiaWF0IjoxNzUzNjcwMTEyfQ.ifaIeAEp6SWTZTbQ2iZxPJrVVcn-MuI9C5E9zbGmLsk'


class Colors:
    """ANSI颜色代码类"""
    # 基础颜色
    RED = '\033[91m'
    GREEN = '\033[92m'
    YELLOW = '\033[93m'
    BLUE = '\033[94m'
    MAGENTA = '\033[95m'
    CYAN = '\033[96m'
    WHITE = '\033[97m'
    GRAY = '\033[90m'

    # 样式
    BOLD = '\033[1m'
    DIM = '\033[2m'
    UNDERLINE = '\033[4m'

    # 重置
    RESET = '\033[0m'

    # 层级颜色系统 (从最重要到最细节)
    TITLE = BOLD + CYAN      # Level 0: 主标题
    SECTION = BOLD + GREEN   # Level 1: 分区标题
    ITEM = YELLOW           # Level 2: 主要条目
    DETAIL = BLUE           # Level 3: 详细信息
    SUBDETAIL = MAGENTA     # Level 4: 子详细信息  
    CONTENT = WHITE         # Level 5: 内容文本
    MUTED = DIM + GRAY      # Level 6: 最深层级/备注

    # 功能性颜色
    WARNING = BOLD + RED    # 警告
    SUCCESS = GREEN         # 成功


def colorize(text: str, color: str) -> str:
    """为文本添加颜色"""
    return f"{color}{text}{Colors.RESET}"


class LevelColorManager:
    """层级颜色管理器"""
    
    # 定义层级颜色映射
    LEVEL_COLORS = {
        0: Colors.TITLE,      # 主标题
        1: Colors.SECTION,    # 分区标题  
        2: Colors.ITEM,       # 主要条目
        3: Colors.DETAIL,     # 详细信息
        4: Colors.SUBDETAIL,  # 子详细信息
        5: Colors.CONTENT,    # 内容文本
        6: Colors.MUTED       # 最深层级
    }
    
    @classmethod
    def get_color_by_level(cls, level: int) -> str:
        """根据层级获取对应颜色"""
        return cls.LEVEL_COLORS.get(level, Colors.MUTED)
    
    @classmethod  
    def colorize_by_level(cls, text: str, level: int) -> str:
        """根据层级为文本着色"""
        color = cls.get_color_by_level(level)
        return colorize(text, color)


def format_vmid_list(vmids: List, max_per_line: int = None) -> List[str]:
    """格式化VMID列表，支持换行显示"""
    if not vmids:
        return []
    
    if max_per_line is None:
        max_per_line = Config.DEFAULT_VMID_PER_LINE

    vmid_strs = [str(vmid) for vmid in vmids]
    result_lines = []

    for i in range(0, len(vmid_strs), max_per_line):
        chunk = vmid_strs[i:i + max_per_line]
        result_lines.append(','.join(chunk))

    return result_lines


def get_auth_token() -> str:
    """获取认证Token"""
    return Config.AUTH_TOKEN


def get_system_images_by_ecm(emc_id: int, show_detail: bool = False) -> Tuple[Optional[List], Optional[str]]:
    """
    通过 EMC ID 获取系统镜像数据（用于系统镜像版本分析）
    Args:
        emc_id: EMC ID
        show_detail: 是否显示详细信息
    Returns:
        Tuple[Optional[List], Optional[str]]: (系统镜像数据列表, 错误信息)
    """
    try:
        url_instance = f'{Config.API_BASE_URL}/cginstance/v1/instance/list'
        headers = {'Authorization': get_auth_token()}
        all_instances = []
        page_no = 1
        while True:
            data = {
                "page": {"no": page_no, "size": Config.DEFAULT_PAGE_SIZE},
                "ecns": [str(emc_id)],
                "systemLabels": [],
                "customizeLabels": [],
                "projectIds": [],
                "resourceType": 1,
                "arches": ["X86"],
                "includeVmInfo": True
            }
            response = requests.post(url=url_instance, headers=headers, json=data, timeout=Config.REQUEST_TIMEOUT)
            if not response.ok:
                error_msg = f"Instance API请求失败: HTTP {response.status_code}, {response.text}"
                ERROR.logger.error(error_msg)
                return None, error_msg
            result = response.json()
            if show_detail:
                INFO.logger.info(f"第{page_no}页Instance数据: {result}")
            # 获取数据
            body = result.get('body', {})
            current_instances = body.get('instances', [])
            total = body.get('total', 0)
            if not current_instances:  # 没有更多数据了
                break
            all_instances.extend(current_instances)
            # 检查是否需要继续获取下一页
            if len(all_instances) >= total:
                break
            page_no += 1
        return all_instances, None
    except requests.RequestException as e:
        error_msg = f"Instance API网络请求异常: {str(e)}"
        ERROR.logger.error(error_msg)
        return None, error_msg
    except Exception as e:
        error_msg = f"Instance API未知错误: {str(e)}"
        ERROR.logger.error(error_msg)
        return None, error_msg


# ================== 数据获取层 ==================

def fetch_vm_data_from_api(emc_id: int, show_detail: bool = False) -> Tuple[Optional[List[Dict]], int, Optional[str]]:
    """
    纯数据获取：从API获取虚拟机原始数据
    Returns:
        Tuple[List[Dict], int, Optional[str]]: (虚拟机列表, 总数, 错误信息)
    """
    try:
        url = f'{Config.API_BASE_URL}/cginstance/v1/vm/list'
        headers = {'Authorization': get_auth_token()}

        all_vms = []
        page_no = 1
        total = 0
        
        while True:
            data = {
                "page": {"no": page_no, "size": Config.DEFAULT_PAGE_SIZE},
                "ecns": [str(emc_id)],
                "systemLabels": [],
                "customizeLabels": [],
                "projectIds": [],
                "resourceType": 1,
                "arches": ["X86"],
                "includeInstanceInfo": True
            }
            
            response = requests.post(url=url, headers=headers, json=data, timeout=Config.REQUEST_TIMEOUT)
            if not response.ok:
                error_msg = f"API请求失败: HTTP {response.status_code}, {response.text}"
                ERROR.logger.error(error_msg)
                return None, 0, error_msg
                
            result = response.json()
            if show_detail:
                INFO.logger.info(f"第{page_no}页数据: {result}")
                
            # 获取数据
            body = result.get('body', {})
            current_vms = body.get('vms', [])
            total = body.get('total', 0)
            
            if not current_vms:
                break
                
            all_vms.extend(current_vms)
            
            if len(all_vms) >= total:
                break
                
            page_no += 1
            
        return all_vms, total, None
        
    except requests.RequestException as e:
        error_msg = f"网络请求异常: {str(e)}"
        ERROR.logger.error(error_msg)
        return None, 0, error_msg
    except Exception as e:
        error_msg = f"未知错误: {str(e)}"
        ERROR.logger.error(error_msg)
        return None, 0, error_msg


def build_ginstance_vmid_mapping(vms: List[Dict]) -> Dict[str, str]:
    """
    数据处理：构建gInstanceId到VMID的映射字典
    """
    ginstance_to_vmid = {}
    for vm in vms:
        ginstance_id = vm.get('ginstanceid') or vm.get('gInstanceId')
        vmid = vm.get('vmid')
        if ginstance_id and vmid:
            ginstance_to_vmid[ginstance_id] = vmid
    return ginstance_to_vmid


def get_vmids_by_to_ecm(emc_id: int, show_detail: bool = False) -> Tuple[Optional[Dict], Optional[str]]:
    """
    获取虚拟机数据（保持原接口兼容性）
    """
    # 数据获取
    vms, total, error = fetch_vm_data_from_api(emc_id, show_detail)
    if error:
        return None, error
        
    # 数据处理
    ginstance_to_vmid_mapping = build_ginstance_vmid_mapping(vms)
    
    # 显示映射信息
    if ginstance_to_vmid_mapping:
        print(LevelColorManager.colorize_by_level(f"🔗 建立了 {len(ginstance_to_vmid_mapping)} 个 gInstanceId→VMID 映射关系", 1))
    
    # 构建最终响应
    final_response = {
        'body': {
            'vms': vms,
            'total': total,
            'ginstance_to_vmid_mapping': ginstance_to_vmid_mapping
        }
    }
    
    return final_response, None


def get_state_emoji(state: int) -> str:
    """根据状态返回对应的表情"""
    state_map = {
        0: "❓",  # 未知
        1: "🔄",  # 启动中
        2: "✅",  # 健康可用
        3: "⚠️",  # 异常不可用
        4: "🔽",  # 关机中
        5: "⭕",  # 已关机
        6: "🔄",  # 重启中
        7: "🟢",  # windows已经启动
        8: "❌",  # NvFBC异常
        9: "🎮",  # 手柄异常
        10: "⏰",  # NvFBC超时
        11: "🎯",  # steam未登录
        12: "🔸",  # 未安装steam
        13: "🔥",  # 显卡驱动异常
        14: "🎵",  # 音频异常
        15: "🔧",  # 音频驱动异常
        16: "⚡",  # 功耗异常
        17: "🌡️",  # 温度异常
        18: "📶",  # 网络异常
        19: "🏃",  # 逃逸进程异常
        20: "📊",  # 性能监控异常
        21: "📱",  # 显卡异常
        26: "🚨",  # 预启动异常
        1000: "🎮",  # 游戏盘/游戏进程异常
    }
    return state_map.get(state, "❓")


def get_state_description(state: int) -> str:
    """根据状态返回对应的描述"""
    state_desc = {
        0: "未知",
        1: "启动中",
        2: "健康可用",
        3: "异常不可用",
        4: "关机中",
        5: "已关机",
        6: "重启中",
        7: "windows已经启动",
        8: "NvFBC异常",
        9: "手柄异常",
        10: "NvFBC超时",
        11: "steam未登录",
        12: "未安装steam",
        13: "显卡驱动异常",
        14: "音频异常",
        15: "音频驱动异常",
        16: "功耗异常",
        17: "温度异常",
        18: "网络异常",
        19: "逃逸进程异常",
        20: "性能监控异常",
        21: "显卡异常",
        26: "预启动异常",
        1000: "游戏盘/游戏进程异常",
    }
    return state_desc.get(state, f"未知状态({state})")


def get_status_emoji(status: int) -> str:
    """根据status状态返回对应的表情"""
    status_map = {
        1: "🔄",  # 外部调度
        2: "⚙️",  # 内部调度
        3: "⚠️",  # 调度异常
        4: "🔧",  # 自动维护中
        5: "🐛",  # 调试中
    }
    return status_map.get(status, "❓")


def get_status_description(status: int) -> str:
    """根据status状态返回对应的描述"""
    status_desc = {
        1: "外部调度",
        2: "内部调度",
        3: "调度异常",
        4: "自动维护中",
        5: "调试中",
    }
    return status_desc.get(status, f"未知状态({status})")


# ================== 通用工具函数 ==================

def normalize_commas(text: str) -> str:
    """将字符串中的中文逗号转换为英文逗号"""
    if text is None:
        return ""
    return str(text).replace('，', ',')


class StatisticsHelper:
    """通用统计工具类"""
    
    @staticmethod
    def group_and_count_by_field(items: List[Dict], field_name: str, extra_fields: List[str] = None) -> Tuple[Dict[Any, int], Dict[Any, List]]:
        """
        按指定字段分组统计
        Args:
            items: 要统计的项目列表
            field_name: 分组字段名
            extra_fields: 需要额外保存的字段列表
        Returns:
            Tuple[统计字典, 详细数据字典]
        """
        count_dict = {}
        detail_dict = {}
        
        for item in items:
            field_value = item.get(field_name, 'Unknown')
            
            # 构建详细信息
            detail_info = {'item': item}
            if extra_fields:
                for extra_field in extra_fields:
                    detail_info[extra_field] = item.get(extra_field)
            
            # 统计计数
            if field_value in count_dict:
                count_dict[field_value] += 1
                detail_dict[field_value].append(detail_info)
            else:
                count_dict[field_value] = 1
                detail_dict[field_value] = [detail_info]
                
        return count_dict, detail_dict
    
    @staticmethod
    def find_main_version(count_dict: Dict[Any, int]) -> Tuple[Any, int]:
        """找出最常见的版本（主流版本）"""
        if not count_dict:
            return None, 0
        return max(count_dict.items(), key=lambda x: x[1])
    
    @staticmethod
    def get_anomaly_versions(count_dict: Dict[Any, int], main_version: Any) -> Dict[Any, int]:
        """获取异常版本（非主流版本）"""
        return {k: v for k, v in count_dict.items() if k != main_version}


class StatusFormatter:
    """状态格式化工具类"""
    
    @staticmethod
    def format_state_info(state: int) -> Tuple[str, str]:
        """格式化OS状态信息"""
        emoji = get_state_emoji(state)
        desc = get_state_description(state)
        return emoji, desc
    
    @staticmethod
    def format_status_info(status: int) -> Tuple[str, str]:
        """格式化资源状态信息"""
        emoji = get_status_emoji(status)
        desc = get_status_description(status)
        return emoji, desc
    
    @staticmethod
    def get_status_color(status_type: str, status_value: Any) -> str:
        """根据状态类型和值获取相应颜色"""
        if status_type == 'os_state':
            return Colors.SUCCESS if status_value == 2 else Colors.ITEM
        elif status_type == 'machine_status':
            if status_value == 2:
                return Colors.SUCCESS
            elif status_value == 3:
                return Colors.WARNING
            else:
                return Colors.ITEM
        else:
            return Colors.ITEM


# ================== 显示工具函数 ==================

def _display_vmid_list_with_tree_structure(vmids: List, item_index: int, total_items: int) -> None:
    """使用树形结构显示VMID列表"""
    if not vmids:
        return
        
    vmid_lines = format_vmid_list(vmids)
    
    for j, vmid_line in enumerate(vmid_lines):
        inner_prefix = "    " if item_index == total_items - 1 else "  │ "
        line_indicator = "└─" if j == len(vmid_lines) - 1 else "├─"
        vmid_prefix = "VMID:" if j == 0 else "     "
        print(f"{inner_prefix}   {LevelColorManager.colorize_by_level(f'{line_indicator} {vmid_prefix} {vmid_line}', 4)}")


def analyze_os_state_statistics(vms: List[Dict[str, Any]], emc_id: int) -> None:
    """分析并显示OS状态统计"""
    # 使用通用统计工具
    osstate_count, osstate_details = StatisticsHelper.group_and_count_by_field(vms, 'osState', ['vmid'])
    
    print(f"\n{LevelColorManager.colorize_by_level(f'📈 {emc_id} 机房--OS状态统计:', 0)}")
    osstate_items = list(osstate_count.items())
    
    for i, (osstate, count) in enumerate(sorted(osstate_items)):
        emoji, desc = StatusFormatter.format_state_info(osstate) if isinstance(osstate, int) else ("❓", str(osstate))
        prefix = "└─" if i == len(osstate_items) - 1 else "├─"
        # 为健康状态使用成功颜色，异常状态使用警告颜色
        level = 1 if osstate == 2 else 2
        
        print(f"  {LevelColorManager.colorize_by_level(f'{prefix} {emoji} {desc}(osState={osstate}): {count}个', level)}")

        # 除了健康可用状态(osState=2)外，显示其他状态的VMID列表
        if osstate != 2:
            vmids = [detail['vmid'] for detail in osstate_details[osstate]]
            _display_vmid_list_with_tree_structure(vmids, i, len(osstate_items))

    print(f"  {LevelColorManager.colorize_by_level(f'└─ OS状态总计: {len(vms)}个', 1)}\n")


def analyze_status_machine_statistics(vms: List[Dict[str, Any]], emc_id: int) -> None:
    """分析并显示状态机状态统计"""
    # 使用通用统计工具
    status_count, status_details = StatisticsHelper.group_and_count_by_field(vms, 'status', ['vmid'])

    print(f"{LevelColorManager.colorize_by_level(f'🔄 {emc_id} 机房--状态机状态统计:', 0)}")
    status_items = list(status_count.items())
    
    for i, (status, count) in enumerate(sorted(status_items)):
        emoji, desc = StatusFormatter.format_status_info(status) if isinstance(status, int) else ("❓", str(status))
        prefix = "└─" if i == len(status_items) - 1 else "├─"
        
        # 为正常状态使用level 1，异常状态使用level 2
        if status in [1, 2]:  # 正常状态
            level = 1  
        elif status == 3:  # 调度异常，警告级别
            level = 2
        else:  # 其他异常状态
            level = 2
        
        print(f"  {LevelColorManager.colorize_by_level(f'{prefix} {emoji} {desc}(status={status}): {count}个', level)}")

        # 除了外部调度(status=1)和内部调度(status=2)，其他状态都显示vmid列表
        if status not in [1, 2]:
            vmids = [detail['vmid'] for detail in status_details[status]]
            _display_vmid_list_with_tree_structure(vmids, i, len(status_items))

    print(f"  {LevelColorManager.colorize_by_level(f'└─ 状态机状态总计: {len(vms)}个', 1)}\n")


def analyze_game_image_versions(vms: List[Dict[str, Any]], emc_id: int) -> None:
    """分析并显示游戏镜像版本信息"""
    version_count = {}
    version_vms = {}  # 记录每个版本对应的虚拟机详情
    
    for vm in vms:
        version = vm.get('gameImageVersion', 'Unknown')
        vmid = vm.get('vmid', 'Unknown')
        remark = normalize_commas(vm.get('remark', ''))
        status = vm.get('status', 'Unknown')
        vm_info = {'vmid': vmid, 'remark': remark, 'status': status}

        if version in version_count:
            version_count[version] += 1
            version_vms[version].append(vm_info)
        else:
            version_count[version] = 1
            version_vms[version] = [vm_info]

    # 找出最常见的版本（大部队版本）
    if version_count:
        main_version = max(version_count.items(), key=lambda x: x[1])[0]
        main_version_count = version_count[main_version]
        
        print(LevelColorManager.colorize_by_level(f"🎮 {emc_id} 机房--游戏镜像版本分析:", 0))
        print(LevelColorManager.colorize_by_level(f"  ├─ 🏆 主流版本: {main_version} ({main_version_count}个)", 1))
        
        # 显示其他版本的虚拟机
        other_versions = {k: v for k, v in version_count.items() if k != main_version}
        if other_versions:
            _display_game_version_anomalies(other_versions, version_vms)
        else:
            print(LevelColorManager.colorize_by_level(f"  ├─ ✅ 所有虚拟机都使用相同版本", 1))

        print(LevelColorManager.colorize_by_level(f"  └─ 游戏镜像版本总计: {len(vms)}个", 1) + "\n")


def _display_game_version_anomalies(other_versions: Dict, version_vms: Dict) -> None:
    """显示游戏镜像版本异常情况的详细信息"""
    print(LevelColorManager.colorize_by_level(f"  ├─ ⚠️ 异常版本虚拟机:", 1))
    other_version_items = list(other_versions.items())
    
    for i, (version, count) in enumerate(sorted(other_version_items)):
        vm_infos = version_vms[version]
        prefix = "  │   └─" if i == len(other_version_items) - 1 else "  │   ├─"
        print(LevelColorManager.colorize_by_level(f"{prefix} 版本 {version} ({count}个):", 2))
        
        # 按status状态分组
        status_groups = {}
        for vm_info in vm_infos:
            status = vm_info['status']
            if status not in status_groups:
                status_groups[status] = []
            status_groups[status].append(vm_info)
        
        # 按状态显示虚拟机
        _display_status_groups(status_groups, i, len(other_version_items))


def _display_status_groups(status_groups: Dict, version_index: int, total_versions: int) -> None:
    """显示状态分组信息"""
    status_items = list(status_groups.items())
    
    for j, (status, status_vm_infos) in enumerate(sorted(status_items)):
        status_emoji = get_status_emoji(status)
        status_desc = get_status_description(status)
        
        # 状态分组的前缀
        if version_index == total_versions - 1:  # 最后一个版本
            status_prefix = "      └─" if j == len(status_items) - 1 else "      ├─"
        else:  # 不是最后一个版本
            status_prefix = "  │   │   └─" if j == len(status_items) - 1 else "  │   │   ├─"
        
        print(LevelColorManager.colorize_by_level(f"{status_prefix} {status_emoji} {status_desc} ({len(status_vm_infos)}个):", 3))

        _display_vm_details(status_vm_infos, version_index, total_versions, j, len(status_items))


def _display_vm_details(status_vm_infos: List, version_index: int, total_versions: int,
                        status_index: int, total_statuses: int) -> None:
    """显示虚拟机详细信息"""
    # 在每个状态下按备注分组显示虚拟机
    no_remark_vms = []  # 无备注的虚拟机
    remark_vms = []  # 有备注的虚拟机
    
    for vm_info in status_vm_infos:
        vmid = vm_info['vmid']
        remark = vm_info['remark']
        
        if not remark:
            no_remark_vms.append(vmid)
        else:
            remark_vms.append((vmid, remark))
    
    # 显示结果
    display_items = []
    if no_remark_vms:
        vmids_str = ','.join(str(vmid) for vmid in no_remark_vms)
        display_items.append(('no_remark', f"VMID: {vmids_str}, 备注: 无"))
    
    for vmid, remark in remark_vms:
        display_items.append(('remark', f"备注: {vmid} :{remark}"))
    
    # 输出显示项
    for k, (item_type, content) in enumerate(display_items):
        # VM详情的前缀
        if version_index == total_versions - 1:  # 最后一个版本
            if status_index == total_statuses - 1:  # 最后一个状态
                vm_prefix = "          └─" if k == len(display_items) - 1 else "          ├─"
            else:  # 不是最后一个状态
                vm_prefix = "      │   └─" if k == len(display_items) - 1 else "      │   ├─"
        else:  # 不是最后一个版本
            if status_index == total_statuses - 1:  # 最后一个状态
                vm_prefix = "  │   │       └─" if k == len(display_items) - 1 else "  │   │       ├─"
            else:  # 不是最后一个状态
                vm_prefix = "  │   │   │   └─" if k == len(display_items) - 1 else "  │   │   │   ├─"
        
        # 使用Level 4或5的颜色，备注信息使用更深的层级
        level = 5 if item_type == 'remark' else 4
        print(LevelColorManager.colorize_by_level(f"{vm_prefix} {content}", level))


def analyze_schedule_image_versions(vms: List[Dict[str, Any]], emc_id: int) -> None:
    """分析并显示调度镜像版本信息"""
    # 使用通用统计工具
    version_count, version_details = StatisticsHelper.group_and_count_by_field(vms, 'imageVersion', ['vmid'])
    
    if not version_count:
        return

    # 找出主流版本
    main_version, main_count = StatisticsHelper.find_main_version(version_count)
    anomaly_versions = StatisticsHelper.get_anomaly_versions(version_count, main_version)

    print(LevelColorManager.colorize_by_level(f"📋 {emc_id} 机房--调度镜像版本分析:", 0))
    print(LevelColorManager.colorize_by_level(f"  ├─ 🏆 主流版本: {main_version} ({main_count}个)", 1))

    # 显示异常版本
    if anomaly_versions:
        print(LevelColorManager.colorize_by_level(f"  ├─ ⚠️ 异常版本虚拟机:", 1))
        anomaly_items = list(anomaly_versions.items())
        
        for i, (version, count) in enumerate(sorted(anomaly_items)):
            vmids = [detail['vmid'] for detail in version_details[version]]
            vmid_lines = format_vmid_list(vmids)

            for j, vmid_line in enumerate(vmid_lines):
                if j == 0:  # 第一行显示版本信息
                    prefix = "  │   └─" if i == len(anomaly_items) - 1 else "  │   ├─"
                    print(LevelColorManager.colorize_by_level(f"{prefix} 版本 {version} ({count}个): {vmid_line}", 2))
                else:  # 后续行只显示VMID
                    prefix = "      " if i == len(anomaly_items) - 1 else "  │   "
                    line_indicator = "└─" if j == len(vmid_lines) - 1 else "├─"
                    print(LevelColorManager.colorize_by_level(f"{prefix}   {line_indicator}     {vmid_line}", 3))
    else:
        print(LevelColorManager.colorize_by_level(f"  ├─ ✅ 所有虚拟机都使用相同版本", 1))

    print(LevelColorManager.colorize_by_level(f"  └─ 调度镜像版本总计: {len(vms)}个", 1) + "\n")


def analyze_system_image_versions(emc_id: int, ginstance_to_vmid_mapping: Dict) -> None:
    """分析并显示系统镜像版本信息"""
    instances, instances_error = get_system_images_by_ecm(emc_id, False)
    
    if instances and not instances_error:
        system_image_count = {}
        system_image_instances = {}  # 记录每个系统镜像版本对应的实例
        
        for instance in instances:
            system_image_id = instance.get('systemImageId', 'Unknown')
            instance_id = instance.get('id', 'Unknown')
            ginstance_id = instance.get('ginstanceid') or instance.get('gInstanceId')  # 尝试两种可能的字段名
            
            # 记录实例信息（包含instance_id和ginstance_id）
            instance_info = {
                'instance_id': instance_id,
                'ginstance_id': ginstance_id
            }
            
            if system_image_id in system_image_count:
                system_image_count[system_image_id] += 1
                system_image_instances[system_image_id].append(instance_info)
            else:
                system_image_count[system_image_id] = 1
                system_image_instances[system_image_id] = [instance_info]
        
        # 找出最常见的系统镜像版本（大部队版本）
        if system_image_count:
            _display_system_image_analysis(emc_id, system_image_count, system_image_instances,
                                            ginstance_to_vmid_mapping, len(instances))
        else:
            print(LevelColorManager.colorize_by_level(f"💽 {emc_id} 机房--系统镜像版本分析:", 0))
            print(LevelColorManager.colorize_by_level(f"  └─ ❌ 未找到任何系统镜像数据", 1) + "\n")
    else:
        print(LevelColorManager.colorize_by_level(f"💽 {emc_id} 机房--系统镜像版本分析:", 0))
        print(LevelColorManager.colorize_by_level(f"  └─ ❌ 获取系统镜像数据失败: {instances_error}", 1) + "\n")


def _display_system_image_analysis(emc_id: int, system_image_count: Dict,
                                   system_image_instances: Dict, ginstance_to_vmid_mapping: Dict,
                                   total_instances: int) -> None:
    """显示系统镜像分析结果"""
    main_system_image = max(system_image_count.items(), key=lambda x: x[1])[0]
    main_system_image_count = system_image_count[main_system_image]
    
    print(LevelColorManager.colorize_by_level(f"💽 {emc_id} 机房--系统镜像版本分析:", 0))
    print(LevelColorManager.colorize_by_level(f"  ├─ 🏆 主流版本: {main_system_image} ({main_system_image_count}个)", 1))
    
    # 显示其他系统镜像版本的实例
    other_system_images = {k: v for k, v in system_image_count.items() if k != main_system_image}
    if other_system_images:
        print(LevelColorManager.colorize_by_level(f"  ├─ ⚠️ 异常版本实例:", 1))
        _display_system_image_anomalies(other_system_images, system_image_instances,
                                        ginstance_to_vmid_mapping)
    else:
        print(LevelColorManager.colorize_by_level(f"  ├─ ✅ 所有实例都使用相同版本", 1))

    print(LevelColorManager.colorize_by_level(f"  └─ 系统镜像版本总计: {total_instances}个", 1) + "\n")


def _display_system_image_anomalies(other_system_images: Dict, system_image_instances: Dict,
                                    ginstance_to_vmid_mapping: Dict) -> None:
    """显示系统镜像异常版本详情"""
    other_system_image_items = list(other_system_images.items())
    
    for i, (image_id, count) in enumerate(sorted(other_system_image_items)):
        instances_list = system_image_instances[image_id]
        prefix = "  │   └─" if i == len(other_system_image_items) - 1 else "  │   ├─"
        print(LevelColorManager.colorize_by_level(f"{prefix} 镜像 {image_id} ({count}个):", 2))
        
        # 显示每个实例及其对应的vmid
        for j, instance_info in enumerate(instances_list):
            instance_id = instance_info['instance_id']
            ginstance_id = instance_info['ginstance_id']
            
            # 通过gInstanceId查找对应的vmid
            vmid = ginstance_to_vmid_mapping.get(ginstance_id, '未找到')
            
            # 确定子项的前缀
            if i == len(other_system_image_items) - 1:  # 最后一个镜像
                sub_prefix = "        └─" if j == len(instances_list) - 1 else "        ├─"
            else:  # 不是最后一个镜像
                sub_prefix = "  │       └─" if j == len(instances_list) - 1 else "  │       ├─"
            
            if vmid != '未找到':
                print(LevelColorManager.colorize_by_level(f"{sub_prefix} 实例ID: {instance_id}, gInstanceId: {ginstance_id} → VMID: {vmid}", 3))
            else:
                print(LevelColorManager.colorize_by_level(f"{sub_prefix} 实例ID: {instance_id}, gInstanceId: {ginstance_id} → VMID: ❌未找到映射", 3))


def main(emc_id: int):
    """主函数 - 协调各个分析模块"""
    print("\n" + LevelColorManager.colorize_by_level("═" * 80, 0))
    print(LevelColorManager.colorize_by_level(f"🔍 开始获取 EMC ID: {emc_id} 的虚拟机数据", 0))
    print(LevelColorManager.colorize_by_level("═" * 80, 0) + "\n")

    # 获取虚拟机数据
    response, error = get_vmids_by_to_ecm(emc_id)
    if error:
        print(LevelColorManager.colorize_by_level(f"❌ 错误: {error}", 0))
        return None

    vms = response.get('body', {}).get('vms', [])
    total = response.get('body', {}).get('total', 0)

    if not vms:
        print(LevelColorManager.colorize_by_level("⚠️ 未找到任何虚拟机数据", 0))
        return None

    # 显示总览信息
    print(LevelColorManager.colorize_by_level(f"📊 总览:", 0))
    print(LevelColorManager.colorize_by_level(f"  └─ 虚拟机总数: {total}", 1))
    print("\n" + LevelColorManager.colorize_by_level("─" * 80, 1))

    # 分模块执行分析
    analyze_os_state_statistics(vms, emc_id)
    analyze_status_machine_statistics(vms, emc_id)
    analyze_game_image_versions(vms, emc_id)
    analyze_schedule_image_versions(vms, emc_id)

    # 获取映射关系并分析系统镜像版本
    ginstance_to_vmid_mapping = response.get('body', {}).get('ginstance_to_vmid_mapping', {})
    analyze_system_image_versions(emc_id, ginstance_to_vmid_mapping)

    print("\n" + LevelColorManager.colorize_by_level("═" * 80, 0) + "\n")
    return response


if __name__ == '__main__':
    main(emc_id=7503)